#include "los_task.h"
#include "ohos_init.h"
#include "los_sem.h"
#include <string.h>

/* 任务ID */
static UINT32 g_testTaskId01;
static UINT32 g_testTaskId02;
static UINT32 g_testTaskId03;
static UINT32 g_testTaskId04;

/* 测试任务优先级 */
#define TASK_PRIO_TEST  5

/* 信号量结构体id */
static UINT32 g_semId;

void ExampleSemTask1(void)
{
    UINT32 ret;

    printf("<<==>>SemTask1 start\n");
    while(1){
        printf("<<==>>SemTask1 start wait forever.\n");
        /*永久阻塞模式申请信号量*/
        ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
        printf("<<==>>SemTask1  get sem.\n");
        if (ret == LOS_OK) {
            /* 任务休眠5s */
            LOS_Msleep(5000);
            printf("<<==>>SemTask1 post sem.\n");
            /* 释放信号量 */
            LOS_SemPost(g_semId);
        }
    }
}

void ExampleSemTask2(void)
{
    UINT32 ret;
    printf("<<==>>SemTask2 start\n");
    while(1){
        printf("<<==>>SemTask2 start wait forever.\n");
        /* 永久阻塞模式申请信号量 */
        ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
        printf("<<==>>SemTask2 get sem.\n");
        if (ret == LOS_OK) {
            /* 任务休眠5s */
            LOS_Msleep(5000);
            printf("<<==>>SemTask2 post sem.\n");
            /* 释放信号量 */
            LOS_SemPost(g_semId);
        }
    }
    return;
}

void ExampleSemTask3(void)
{
    UINT32 ret;
    printf("<<==>>SemTask3 start\n");
    while(1){
        printf("<<==>>SemTask3 start wait forever.\n");
        /* 永久阻塞模式申请信号量 */
        ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
        printf("<<==>>SemTask3 get sem.\n");
        if (ret == LOS_OK) {
            printf("<<==>>SemTask3 post sem.\n");
            /* 释放信号量 */
            LOS_SemPost(g_semId);
        }
    }
    return;
}

void ExampleSemTask4(void)
{
    UINT32 ret;
    printf("<<==>>SemTask4 start\n");
    while(1){
        printf("<<==>>SemTask4 start wait forever.\n");
        /* 永久阻塞模式申请信号量 */
        ret = LOS_SemPend(g_semId, LOS_WAIT_FOREVER);
        printf("<<==>>SemTask4 get sem.\n");
        if (ret == LOS_OK) {
            printf("<<==>>SemTask4 post sem.\n");
            /* 释放信号量 */
            LOS_SemPost(g_semId);
        }
    }
    return;
}

UINT32 ExampleSem(void)
{
    UINT32 ret;
    TSK_INIT_PARAM_S task1;
    TSK_INIT_PARAM_S task2;
    TSK_INIT_PARAM_S task3;
    TSK_INIT_PARAM_S task4;

   /* 创建信号量 */
    LOS_SemCreate(1, &g_semId);
    /* 锁任务调度 */
    LOS_TaskLock();

    /* 创建任务1 */
    (void)memset_s(&task1, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
    task1.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask1;
    task1.pcName       = "TestTask1";
    task1.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    task1.usTaskPrio   = TASK_PRIO_TEST;
    ret = LOS_TaskCreate(&g_testTaskId01, &task1);
    if (ret != LOS_OK) {
        printf("task1 create failed .\n");
        return LOS_NOK;
    }
	
    /* 创建任务2 */
    (void)memset_s(&task2, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
    task2.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask2;
    task2.pcName       = "TestTask2";
    task2.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    task2.usTaskPrio   = (TASK_PRIO_TEST );
    ret = LOS_TaskCreate(&g_testTaskId02, &task2);
    if (ret != LOS_OK) {
        printf("task2 create failed.\n");
        return LOS_NOK;
    }

     /* 创建任务3 */
    (void)memset_s(&task3, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
    task3.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask3;
    task3.pcName       = "TestTask3";
    task3.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    task3.usTaskPrio   = (TASK_PRIO_TEST );
    ret = LOS_TaskCreate(&g_testTaskId03, &task3);
    if (ret != LOS_OK) {
        printf("task3 create failed.\n");
        return LOS_NOK;
    }
    /* 创建任务4 */
    (void)memset_s(&task4, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
    task4.pfnTaskEntry = (TSK_ENTRY_FUNC)ExampleSemTask4;
    task4.pcName       = "TestTask4";
    task4.uwStackSize  = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
    task4.usTaskPrio   = (TASK_PRIO_TEST );
    ret = LOS_TaskCreate(&g_testTaskId04, &task4);
    if (ret != LOS_OK) {
        printf("task4 create failed.\n");
        return LOS_NOK;
    }

    /* 解锁任务调度 */
    LOS_TaskUnlock();

    ret = LOS_SemPost(g_semId);
    printf("<<==>>g_semId create open\n");
    return LOS_OK;
}